package jp.kentaro.plugin.memoryimageview.client.views;

import java.util.ArrayList;
import java.util.List;

import memoryimage.models.ByteDataArray;
import memoryimage.models.MemoryImage;
import memoryimage.provider.MemoryContentProvider;
import memoryimage.provider.MemoryLabelProvider;
import memoryimage.provider.MemoryModifier;

import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;

import socketinterface.ClientController;
import socketinterface.MemoryImageProtocol;
import socketinterface.PacketData;
import socketinterface.ServerController;

public class ViewPart extends org.eclipse.ui.part.ViewPart {
	public Display       display;
	Image         image;
	MemoryImage   memoryImage;
	public Text          consoleBox;
	List<String>  logMessages;
	Text hostName;
	Text portNumber;
	TableViewer viewer;
	ServerController serverController;
	ClientController clientController;
	
	public ViewPart() {
		// TODO Auto-generated constructor stub
	}
	
	public int getAsUnsignedInteger(byte byteValue) {
		return Integer.valueOf(128 + (byteValue - 128));
	}
	
	public byte fromIntegerToByte(int intValue) {
		if (intValue < 127) {
			return (byte)intValue;
		}else {
			return (byte)(intValue - 255);
		}
	}
	
	public void startServerController() {
		serverController = new ServerController(this);
		serverController.startServer();
	}
	
	public void startClientController() throws Exception {
		clientController = new ClientController(this);
		clientController.setHostName(hostName.getText());
		clientController.setPortNumber(portNumber.getText());
		clientController.connectToServer();
	}
	
	@Override
	public void createPartControl(Composite parent) {
		// TODO Auto-generated method stub
		display    = parent.getDisplay();
		GridLayout layout = new GridLayout();
		layout.numColumns = 4;
		parent.setLayout(layout);
		    
		GridData layoutData = null;
		
		layoutData = new GridData();    
		hostName = new Text(parent, SWT.SINGLE);
		hostName.setText("192.168.12.2");
		hostName.pack();
		hostName.setLayoutData(layoutData);
		
		layoutData = new GridData(); 
		portNumber = new Text(parent, SWT.SINGLE);
		portNumber.setText("20000");
		portNumber.pack();
		portNumber.setLayoutData(layoutData);

		layoutData = new GridData(); 
		Button sendButton = new Button(parent, SWT.PUSH);
		sendButton.setText("Send");
		sendButton.addSelectionListener(new SelectionAdapter(){
			  public void widgetSelected(SelectionEvent e){
				  List<ByteDataArray> byteDataArrayList = memoryImage.getList();
				  for(ByteDataArray byteDataArray : byteDataArrayList) {
					  clientController.send(MemoryImageProtocol.PK_MEMORY_UPDATE, byteDataArray.cells);
				  }
			  }
		});
		sendButton.setLayoutData(layoutData);
		
		layoutData = new GridData(GridData.FILL_BOTH);
		layoutData.horizontalSpan = 3;
		consoleBox = new Text(parent,SWT.MULTI|SWT.BORDER|SWT.H_SCROLL|SWT.V_SCROLL);
		logMessages = new ArrayList<String>();
		consoleBox.setLayoutData(layoutData);

		
	    //consoleText.add("aiueo");
		//consoleBox.setText(consoleText.get(0));
	    
		Table table = new Table(parent, SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		
		// Create Header of Table
		String[] labels = new String[] { "Address(h)", "+0", "+1", "+2", "+3", "+4", "+5", "+6", "+7", "+8", "+9", "+A", "+B", "+C", "+D", "+E", "+F"};
		for (String label : labels) {
			TableColumn column = new TableColumn(table, SWT.LEFT);
			column.setText(label);
			column.pack();
		}
		
		// Create initial data of MemoryImage
		ByteDataArray byteDataArray = null;
		memoryImage = new MemoryImage();
		byteDataArray = new ByteDataArray(16);
		for(int i = 0; i < 0xFF; i++) {
			if(i != 0 && (i%16 == 0)) {
				memoryImage.add(byteDataArray);
				byteDataArray = new ByteDataArray(16);
			}
			byteDataArray.cells[i % 16] = (byte)i;
		}
		byteDataArray.cells[15] = (byte)0xFF;
		memoryImage.add(byteDataArray);
		
		// Set Editor
		CellEditor[] editors = new CellEditor[labels.length];
		for (int i = 0; i < labels.length; i++) {
			editors[i] = new TextCellEditor(table);
		}
		FormData viewerForm = new FormData();
		viewerForm.top = new FormAttachment(0, 1);
		viewerForm.left = new FormAttachment(consoleBox, 1);
		viewerForm.right = new FormAttachment(100, -1);
		// Set ContentProvider
		viewer = new TableViewer(table);
		viewer.setContentProvider(new MemoryContentProvider());
		
		// Set LabelProvider
		viewer.setLabelProvider(new MemoryLabelProvider(parent.getDisplay()));
		
		// Set CellEditor and CellModifier
		viewer.setColumnProperties(labels);
		viewer.setCellEditors(editors);
		viewer.setCellModifier(new MemoryModifier(viewer));
		
		// Set MemoryImage into the table viewer
		viewer.setInput(memoryImage);
		
		Button updateButton = new Button(parent, SWT.PUSH);
		updateButton.setText("Update");
		updateButton.addSelectionListener(new SelectionAdapter(){
			  public void widgetSelected(SelectionEvent e){
				  List<ByteDataArray> byteDataArrayList = memoryImage.getList();
				  int baseAddress = 0xFF200000;
				  for(ByteDataArray byteDataArray : byteDataArrayList) {
					 byteDataArray.address = baseAddress & 0xFFFFFFFF;
					 baseAddress += 0x10;
					 viewer.update(byteDataArray, null);
				  }
			  }
		});
		
		final Text indexText = new Text(parent,SWT.SINGLE);
		indexText.setText("1");
		Button changeButton = new Button(parent, SWT.PUSH);
		changeButton.setText("Change");
		changeButton.addSelectionListener(new SelectionAdapter(){
			  public void widgetSelected(SelectionEvent e){
				  ByteDataArray target = new ByteDataArray(16);	
				  int index = Integer.parseInt(indexText.getText());
				  target.address = 0xFF212345;
				  for(int i = 0; i < target.cells.length; i++) {
					  target.cells[i] = (byte)i;
				  }
				  memoryImage.changeTarget(index, target);
				  //memoryImage.changeTarget(target);	
				  //viewer.update(target, null);
				  viewer.setInput(memoryImage);
			  }
		});
		

	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}

}
